import { Attributes, TroopType,DamageType } from '../types';
import { BattleAction } from '../types/battle';
import { BaseSkill } from '../skills/BaseSkill';
import { EffectManager } from './Effect';
import { Effect } from '../types/effect';

export class General {
  id: string;
  name: string;
  type: TroopType;
  attributes: Attributes;
  position: number = 0; // 默认位置为0
  troops: number = 30000;
  maxTroops: number = 30000;
  skills: any[] = [];
  equippedSkills: any[] = [];
  private effectManager: EffectManager;

  constructor(
    id: string,
    name: string,
    type: TroopType,
    attributes: Attributes,
    position: number = 0,  // 添加 position 参数并设置默认值
    skills: BaseSkill[] = []
  ) {
    this.id = id;
    this.name = name;
    this.type = type;
    this.attributes = attributes;
    this.position = position;
    this.skills = skills;
    this.equippedSkills = [];
    this.effectManager = new EffectManager();
  }

  addEffect(effect: Effect): void {
    this.effectManager.addEffect(effect);
  }

  // 计算实际伤害
  receiveDamage(damage: number): number {
    // 检查闪避
    if (this.effectManager.hasEffect('dodge')) {
      return 0;
    }

    // 应用伤害减免
    const reduction = this.effectManager.getEffectValue('damageReduction');
    damage *= (1 - reduction);

    // 扣除兵力
    this.troops = Math.max(0, this.troops - Math.floor(damage));
    return this.troops;
  }

  // 计算实际造成的伤害
  calculateOutgoingDamage(baseDamage: number, damageType: DamageType): number {
    let finalDamage = baseDamage;

    // 应用增伤效果
    if (damageType === DamageType.Physical) {
      const physicalBoost = this.effectManager.getEffectValue('physicalDamageBoost');
      finalDamage *= (1 + physicalBoost);
    } else {
      const strategyBoost = this.effectManager.getEffectValue('strategyDamageBoost');
      finalDamage *= (1 + strategyBoost);
    }

    return Math.floor(finalDamage);
  }

  heal(amount: number): void {
    // 确保治疗量为正数
    const healAmount = Math.max(0, amount);
    // 不超过最大兵力
    this.troops = Math.min(this.maxTroops, this.troops + Math.floor(healAmount));
  }

  updateEffects(): void {
    this.effectManager.updateEffects();
  }

  isAlive(): boolean {
    return this.troops > 0;
  }

  async executeAction(battle: any): Promise<BattleAction[]> {
    const actions: BattleAction[] = [];
    
    // 1. 触发被动技能
    const passiveActions = await this.triggerPassiveSkills(battle);
    actions.push(...passiveActions);
    
    // 2. 尝试触发主动技能
    if (passiveActions.length === 0) {
      const activeActions = await this.triggerActiveSkills(battle);
      actions.push(...activeActions);
      
      // 3. 如果没有触发任何技能，执行普通攻击
      if (activeActions.length === 0) {
        const normalAttack = await this.performNormalAttack(battle);
        if (normalAttack) {
          actions.push(normalAttack);
        }
      }
    }
    
    return actions;
  }

  private async triggerPassiveSkills(battle: any): Promise<BattleAction[]> {
    const actions: BattleAction[] = [];
    const passiveSkills = [...this.skills, ...this.equippedSkills]
      .filter(skill => skill.type === 'passive');
    
    for (const skill of passiveSkills) {
      const action = await skill.execute(this, battle);
      if (action) {
        actions.push(action);
      }
    }
    
    return actions;
  }

  private async triggerActiveSkills(battle: any): Promise<BattleAction[]> {
    const actions: BattleAction[] = [];
    const activeSkills = [...this.skills, ...this.equippedSkills]
      .filter(skill => skill.type === 'active');
    
    for (const skill of activeSkills) {
      if (skill.canUse() && Math.random() <= skill.probability) {
        const action = await skill.execute(this, battle);
        if (action) {
          actions.push(action);
          skill.startCooldown();
        }
      }
    }
    
    return actions;
  }

  private async performNormalAttack(battle: any): Promise<BattleAction | null> {
    const target = battle.selectTarget(this);
    if (!target) return null;

    const damage = battle.calculateDamage(this, target, DamageType.Physical);
    
    return {
      actor: this,
      target,
      type: 'attack',
      damage
    };
  }
}
